/**
 * @file app_control.c
 * @brief 应用控制文件
 * @author liucx (liucx@fiberhome.com)
 * @version 1.0
 * @date 2020-11-30
 * @copyright Copyright (c) 2020  烽火通信
 ***************************************************************
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version  <th>Author  <th>Description
 * <tr><td>2020-11-30 <td>1.0      <td>liucx   <td>内容
 * </table>
 */
#include "project_config.h"
#if BOARD_PCU_EN
#include "app_control.h"
#include "app_data.h"
#include "project_board.h"
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"
#include <string.h>
#include <stdlib.h>
#include "bsp_gpio.h"
#include "bsp_uart_v2.h"
#include "easyflash.h"
#include "drv_hc595_pcu.h"
#include "bsp_dac.h"
#include "bsp_adc.h"
#include "bsp_uart_v2.h"
#include "bl0939.h"
#include "bl0906.h"
#include "drv_misc.h"
#include "bsp_rtc.h"
#include "app_pcu.h"
#include "wiz.h"
#include "wiz_socket.h"
#include "math.h"
#include <string.h>
#include "msc.h"
#include "app_config.h"
#include "alarm.h"
#include "bsp_log.h"
#include "drv_led.h"




/**
 * @brief 智慧电源单回路参数结构体 
 */
typedef struct LOOP_VALUES_s
{
    uint8_t dev_type;
    float max_current;
    float min_current;
}LOOP_VALUES_t;

/**
 * @brief 智慧电源阈值参数结构体 
 */
typedef struct THRESHOLD_s
{
    TILT_TASK_t tilt_task_values;
    LEAKAGE_TASK_t leakage_task_values;
    TEMPERATURE_TASK_t temperature_task_values;
    WEAK_CURRENT_TASK_t weak_current_task_values;
    STRONG_CURRENT_TASK_t strong_current_task_values;
}THRESHOLD_t;

/**
 * @brief 智慧电源开关参数结构体 
 */
typedef struct SWITCH_STATUS_s
{
    ALTERNATING_STATUS_t switch_status_220V; //交流开关状态
    DIRECT_STATUS_t switch_status_direct; //直流开关状态
    uint8_t light_1;        //灯1亮度
    uint8_t light_2;        //灯2亮度
    uint8_t ambient;        //氛围灯模式
    uint8_t DI_1;           //DI1口初始状态
    uint8_t DI_2;           //DI2口初始状态
    uint8_t DI_1_dev_type;
    uint8_t DI_2_dev_type;
}SWITCH_STATUS_t;

/**
 * @brief 智慧电源主结构体 
 */
typedef struct SMART_POWER_s
{
    uint8_t up_type;
    #if BL0939_ENERGY_USE_FLOAT
    float energy_communicate;
    #else
    uint32_t energy_communicate;
    #endif
    #if BL0906_ENERGY_USE_FLOAT
    float energy_light_1;
    float energy_light_2;
    #else
    uint32_t energy_light_1;
    uint32_t energy_light_2;
    #endif

    UPGRADE_VALUES_t upgrade_values;
    INFO_t info;
    NET_t net;
    NORTH_CONNECT_t north_connect;
    SERIAL_485_t serial_1;  
    SERIAL_485_t serial_2;
    SWITCH_STATUS_t switch_status;
    THRESHOLD_t threshold;
    LOOP_VALUES_t direct_loop[DIRECT_LOOP_LEN];
    LOOP_VALUES_t alternating_loop[ALTERNATING_LOOP_LEN];
    PLAN_VALUES_t plan_arr[LIGHT_PLAN_MAX_NUM + AMBIENT_PLAN_MAX_NUM];
}SMART_POWER_t;

static SMART_POWER_t smart_power; /* 智能电源对象 */

SemaphoreHandle_t info_lock;             /* 智能电源描述信息锁 */
SemaphoreHandle_t serial_lock;         /* 智能电源485口锁 */
SemaphoreHandle_t switch_status_lock;    /* 智能电源开关状态锁 */
SemaphoreHandle_t threshold_lock;        /* 智能电源阈值锁 */
SemaphoreHandle_t alternating_loop_lock; /* 智能电源交流回路锁 */
SemaphoreHandle_t direct_loop_lock;      /* 智能电源直流回路锁 */
SemaphoreHandle_t plan_lock;             /* 计划锁 */
SemaphoreHandle_t net_lock;             /* 网络参数锁 */
SemaphoreHandle_t upgrade_lock;             /* 升级参数锁 */

Gpio_t alarm_obj;  /* 告警灯对象 */
Gpio_t switch_obj; /* 12V电源开关 */

Gpio_t MCU_DI1_obj; /* 自定义DI1 */
Gpio_t MCU_DI2_obj; /* 自定义DI2 */

pwrDect_t pwrDect_obj; /* 智慧电源DI检测对象 */
pcuDac_t pcuDac_obj;   /* 智慧电源DAC调光对象 */
pcuAdc_t pcuAdc_obj;   /* 智慧电源ADC检测对象 */

Bl0939_t bl0939_obj; /* 2主路电量计量对象 */
Bl0906_t bl0906_obj; /* 6支路电量计量对象 */

LedDrv_t led_obj;    	/* 灯带对象 */

/**
 * @brief smart_power 结构体初始化
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_smart_power_init(void)
{
    uint32 len = 0;
    /* 读取flash */
	ef_get_env_blob("DEVICE_INFO", &smart_power, sizeof(SMART_POWER_t), &len);
    if(0 == len)
    {
        /* 默认值设置 */
        /* 默认阈值 */
        smart_power.threshold.strong_current_task_values.alternating_high_current = ALTERNATING_HIGH_CURRENT;
        smart_power.threshold.weak_current_task_values.direct_high_current = DIRECT_HIGH_CURRENT;
        smart_power.threshold.strong_current_task_values.alternating_high_voltage = ALTERNATING_HIGH_VOLTAGE;
        smart_power.threshold.strong_current_task_values.alternating_low_voltage = ALTERNATING_LOW_VOLTAGE;
        smart_power.threshold.weak_current_task_values.direct_12V_high_voltage = DIRECT_12V_HIGH_VOLTAGE;
        smart_power.threshold.weak_current_task_values.direct_12V_low_voltage = DIRECT_12V_LOW_VOLTAGE;
        smart_power.threshold.weak_current_task_values.direct_24V_high_voltage = DIRECT_24V_HIGH_VOLTAGE;
        smart_power.threshold.weak_current_task_values.direct_24V_low_voltage = DIRECT_24V_LOW_VOLTAGE;
        smart_power.threshold.temperature_task_values.high_temperature = HIGH_TEMPERATURE;
        smart_power.threshold.temperature_task_values.low_temperature = LOW_TEMPERATURE;
        smart_power.threshold.temperature_task_values.fan_temperature = FAN_TEMPERATURE;
        smart_power.threshold.temperature_task_values.heater_temperature = HEATER_TEMPERATURE;
        smart_power.threshold.leakage_task_values.leakage_values = LEAKAGE_VALUES;
        smart_power.threshold.leakage_task_values.leakage_enable = LEAKAGE_ACTION;
        smart_power.threshold.leakage_task_values.leakage_frequency = LEAKAGE_DEFAULT_FREQUENCY;
        smart_power.threshold.leakage_task_values.leakage_times = LEAKAGE_DEFAULT_TIMES;
        smart_power.threshold.tilt_task_values.tilt = TILT_DEFAULT_VALUES;
        /* 默认485参数 */
        smart_power.serial_1.baudrate = BAUDRATE_485_1;
        smart_power.serial_1.databit = 8;
        smart_power.serial_1.stopbit = STOPBIT_485_1;
        smart_power.serial_1.parity = 'n';
        smart_power.serial_1.flowctl = 0;
        smart_power.serial_2.baudrate = BAUDRATE_485_2;
        smart_power.serial_2.databit = 8;
        smart_power.serial_2.stopbit = STOPBIT_485_2;
        smart_power.serial_2.parity = 'n';
        smart_power.serial_2.flowctl = 0;
        /* 默认网络参数 */
        smart_power.info.heartbeat = HEARTBEAT;
        smart_power.net.ip[0] = 192;

		smart_power.net.ip[1] = 168;

		smart_power.net.ip[2] = 1;

		smart_power.net.ip[3] = 254;

		smart_power.net.mask[0] = 255;

		smart_power.net.mask[1] = 255;

		smart_power.net.mask[2] = 255;

		smart_power.net.mask[3] = 0;

		smart_power.net.gateway[0] = 192;

		smart_power.net.gateway[1] = 168;

		smart_power.net.gateway[2] = 1;

		smart_power.net.gateway[3] = 1;
        
        smart_power.north_connect.ip[0] = 192;
        smart_power.north_connect.ip[1] = 168;
        smart_power.north_connect.ip[2] = 1;
        smart_power.north_connect.ip[3] = 253;
        smart_power.north_connect.port = 60000;
        smart_power.upgrade_values.file_total_num = 0;
        smart_power.upgrade_values.upgrade_status = UPGRADE_STATUS_NO;
        smart_power.upgrade_values.subfile_num = 0;
        smart_power.upgrade_values.wait_subfile_no = 0;
        smart_power.switch_status.switch_status_direct.SWITCH_24V = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_direct.SWITCH_12V_1 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_direct.SWITCH_12V_2 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_direct.SWITCH_12V_3 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_direct.SWITCH_485_VCC1 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_direct.SWITCH_485_VCC2 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_220V.v_Power_DECT1 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_220V.v_Power_DECT2 = SWITCH_OPEN ;
        smart_power.switch_status.switch_status_220V.v_Power_DECT3 = SWITCH_OPEN ;
        smart_power.switch_status.light_1 = MAX_LIGHT_VALUES ;
        smart_power.switch_status.light_2 = MAX_LIGHT_VALUES ;
        
        if(EF_NO_ERR != ef_set_env_blob("DEVICE_INFO", &smart_power, sizeof(SMART_POWER_t)))
        {
            return ERROR_COM;
        }
    }
    ef_get_env_blob("UPGRADE_FLAG", NULL, 0, &len);
    if(0 == len)
    {
        if(EF_NO_ERR != ef_set_env_blob("UPGRADE_FLAG", "upgrade_off", 11))
        {
            return ERROR_COM;
        }
    }
    //初始化控制
    app_control_switch_set(AISLE_24V,smart_power.switch_status.switch_status_direct.SWITCH_24V);
    app_control_switch_set(AISLE_12V_1,smart_power.switch_status.switch_status_direct.SWITCH_12V_1);
    app_control_switch_set(AISLE_12V_2,smart_power.switch_status.switch_status_direct.SWITCH_12V_2);
    app_control_switch_set(AISLE_12V_3,smart_power.switch_status.switch_status_direct.SWITCH_12V_3);
    app_control_switch_set(AISLE_12V_485_1,smart_power.switch_status.switch_status_direct.SWITCH_485_VCC1);
    app_control_switch_set(AISLE_12V_485_2,smart_power.switch_status.switch_status_direct.SWITCH_485_VCC2);
    app_control_switch_set(AISLE_220V_1,smart_power.switch_status.switch_status_220V.v_Power_DECT1);
    app_control_switch_set(AISLE_220V_2,smart_power.switch_status.switch_status_220V.v_Power_DECT2);
    app_control_switch_set(AISLE_220V_3,smart_power.switch_status.switch_status_220V.v_Power_DECT3);
    /* 0068936 */
//    app_control_switch_set(AISLE_220V_4,smart_power.switch_status.switch_status_220V.v_Power_DECT4);
//    app_control_switch_set(AISLE_220V_5,smart_power.switch_status.switch_status_220V.v_Power_DECT5);
    app_control_single_light_set(smart_power.switch_status.light_1,smart_power.switch_status.light_2);
    app_control_energy_set();
    return OK;
}

/**
 * @brief 智能电源数据读写锁初始化
 */
void app_control_lock_init(void)
{
    info_lock = xSemaphoreCreateBinary();
    if (NULL != info_lock)
    {
        xSemaphoreGive(info_lock);
    }
    serial_lock = xSemaphoreCreateBinary();
    if (NULL != serial_lock)
    {
        xSemaphoreGive(serial_lock);
    }
    switch_status_lock = xSemaphoreCreateBinary();
    if (NULL != switch_status_lock)
    {
        xSemaphoreGive(switch_status_lock);
    }
    threshold_lock = xSemaphoreCreateBinary();
    if (NULL != threshold_lock)
    {
        xSemaphoreGive(threshold_lock);
    }
    alternating_loop_lock = xSemaphoreCreateBinary();
    if (NULL != alternating_loop_lock)
    {
        xSemaphoreGive(alternating_loop_lock);
    }
    direct_loop_lock = xSemaphoreCreateBinary();
    if (NULL != direct_loop_lock)
    {
        xSemaphoreGive(direct_loop_lock);
    }
    plan_lock = xSemaphoreCreateBinary();
    if (NULL != plan_lock)
    {
        xSemaphoreGive(plan_lock);
    }
    net_lock = xSemaphoreCreateBinary();
    if (NULL != net_lock)
    {
        xSemaphoreGive(net_lock);
    }
    upgrade_lock = xSemaphoreCreateBinary();
    if (NULL != upgrade_lock)
    {
        xSemaphoreGive(upgrade_lock);
    }
}

/**
 * @brief 保存数据
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_save(void)
{
    if(EF_NO_ERR != ef_set_env_blob("DEVICE_INFO", &smart_power, sizeof(SMART_POWER_t)))
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief control模块驱动初始化
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_drv_init(void)
{
    /* RTC初始化 */
    RtcInit();
    /* 电源输出控制HC595初始化 */
    drv_pcuPwrCtr_init();
    /* 电源输出状态获取初始化 */
    drv_pwrDect_init(&pwrDect_obj);
    GpioInit(&alarm_obj, ALARM, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 1);   /* 告警灯引脚 */
    GpioInit(&switch_obj, SWITCH, PIN_OUTPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0); /* switch引脚 */
    /* DI初始化 */
    GpioInit(&MCU_DI1_obj, MCU_DI1, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0);
    GpioInit(&MCU_DI2_obj, MCU_DI2, PIN_INPUT, PIN_PUSH_PULL, PIN_NO_PULL, 0);
    /* DAC初始化 */
    drv_pcuDac_init(&pcuDac_obj);
    /* ADC初始化 */
    drv_pcuAdc_init(&pcuAdc_obj);
    
    led_Init( &led_obj, WS2812, LED_DRIVE, 20 );
    /* BL0939、BL0906初始化 */
    if( BSP_SUCCESS != Bl0939_Init( &bl0939_obj, UART_3, UART3_TX_PIN, UART3_RX_PIN, NC, 5 ) )
    {
        return ERROR_COM;
    }
    
    if( BSP_SUCCESS != Bl0906_Init( &bl0906_obj, UART_2, UART2_TX_PIN, UART2_RX_PIN ) )
    {
        return ERROR_COM;
    }
    return OK;
}


/**
 * @brief control模块初始化
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_init(void)
{
    app_control_drv_init();
    /*锁初始化*/
    app_control_lock_init();
    //开启总开关
    app_control_switch_set(AISLE_DIRECT_LOOP,SWITCH_OPEN);
    app_control_switch_set(AISLE_ALTERNATING_LOOP,SWITCH_OPEN);
    /*结构体初始化*/
    if (OK !=  app_control_smart_power_init())
    {
        return ERROR_COM;
    }

    return OK;
}

/**
 * @brief 开关控制 
 * @param map       开关状态控制位图 DIRECT_MAIN_EN|ALTERNATING_MAIN_EN
 * @param status    1 开启 0 关闭
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_light_switch_set(uint8_t port_num, uint8_t status)
{
	switch (port_num) 
	{
        case AISLE_220V_4:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT4 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M4_EN,false))
                {
                    return ERROR_COM;
                }
            }
            else
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M4_EN,true))
                {
                    return ERROR_COM;
                }
            }            
            break;
        case AISLE_220V_5:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT5 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M5_EN,false))
                {
                    return ERROR_COM;
                }
            }
            else
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M5_EN,true))
                {
                    return ERROR_COM;
                }
            }
            break;            
        default:
            break;
    }
    return OK;
}

/**
 * @brief 开关控制 
 * @param map       开关状态控制位图 DIRECT_MAIN_EN|ALTERNATING_MAIN_EN
 * @param status    1 开启 0 关闭
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_switch_set(uint8_t port_num, uint8_t status)
{
    switch (port_num) 
	{
        case AISLE_24V:
            drv_pcuPwrCtr_Set(PCU_24V_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_24V = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_12V_1:
            drv_pcuPwrCtr_Set(PCU_12VOUT1_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_12V_1 = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_12V_2:
            drv_pcuPwrCtr_Set(PCU_12VOUT2_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_12V_2 = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_12V_3:
            drv_pcuPwrCtr_Set(PCU_12VOUT3_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_12V_3 = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_12V_485_1:
            drv_pcuPwrCtr_Set(PCU_485_VCC2_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_485_VCC1 = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_12V_485_2:
            drv_pcuPwrCtr_Set(PCU_485_VCC1_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_485_VCC2 = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_220V_1:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT1 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M3_EN,false))
                {
                    return ERROR_COM;
                }
            }
            else
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M3_EN,true))
                {
                    return ERROR_COM;
                }
            }

            break;
        case AISLE_220V_2:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT2 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M2_EN,false))
                {
                    return ERROR_COM;
                }
            }
            else
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M2_EN,true))
                {
                    return ERROR_COM;
                }
            }
            
            break;
        case AISLE_220V_3:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT3 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M1_EN,false))
                {
                    return ERROR_COM;
                }
            }
            else
            {
                if(BSP_SUCCESS != Bl0906_SetMn(&bl0906_obj,BL_M1_EN,true))
                {
                    return ERROR_COM;
                }
            }
                    
            break;
        case AISLE_220V_4:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT4 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
				if(OK != app_control_single_light_set(50,LIGHT_NO_ACTION))
				{
					log_e(" light1 control fail \r\n");
					return ERROR_COM;
				}
            }
            else
            {
				if(OK != app_control_single_light_set(0,LIGHT_NO_ACTION))
				{
					log_e(" light1 control fail \r\n");
					return ERROR_COM;
				}
            }       
            break;
        case AISLE_220V_5:
			xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_Power_DECT5 = status;
            xSemaphoreGive(switch_status_lock);
            if(status)
            {
				if(OK != app_control_single_light_set(LIGHT_NO_ACTION,50))
				{
					log_e(" light1 control fail \r\n");
					return ERROR_COM;
				}
            }
            else
            {
				if(OK != app_control_single_light_set(LIGHT_NO_ACTION,0))
				{
					log_e(" light1 control fail \r\n");
					return ERROR_COM;
				}
            }
            break;            
        case AISLE_DIRECT_LOOP:
            GpioWrite( &switch_obj,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_direct.SWITCH_direct_main = status;
            xSemaphoreGive(switch_status_lock);
            break;
        case AISLE_ALTERNATING_LOOP:
            drv_pcuPwrCtr_Set(PCU_AC_Ctr_SET,status);
            xSemaphoreTake(switch_status_lock, portMAX_DELAY);
            smart_power.switch_status.switch_status_220V.v_BAT_CTRL = status;
            xSemaphoreGive(switch_status_lock);  
            break;
        default:
            break;
    }
    return OK;
}

/**
 * @brief 开关状态获取
 * @param map       开关状态
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_switch_get(uint8_t port_num ,uint8_t *status)
{
    uint8_t mask = 0;
    Bl0939_Elect_t  Elect;
    if(status == NULL || port_num > AISLE_ALTERNATING_LOOP || port_num == 0 )
    {
        return ERROR_COM;
    }
    
    if(port_num < AISLE_220V_1)
    {
        drv_pwrCtr_Get(&mask);
        if(port_num < AISLE_12V_485_1)
        {
            if(mask&(1 << (port_num - AISLE_24V)))
            {
                *status = 1;
            }
            else
            {
                *status = 0;
            }
        }
        else if(port_num == AISLE_12V_485_1)
        {
            if(mask&(1 << (AISLE_12V_485_2 - AISLE_24V)))
            {
                *status = 1;
            }
            else
            {
                *status = 0;
            } 
        }
        else
        {
            if(mask&(1 << (AISLE_12V_485_1 - AISLE_24V)))
            {
                *status = 1;
            }
            else
            {
                *status = 0;
            } 
        }

    }
    else if(port_num == AISLE_DIRECT_LOOP)
    {
        *status = GpioRead(&switch_obj);
    }
    else if(port_num == AISLE_ALTERNATING_LOOP)
    {
        /*采集电压判断220V*/
        if(BSP_SUCCESS != Bl0939_GetElect(&bl0939_obj,&Elect,BL0939_ELECT_V))
        {
            return ERROR_COM;
        }

#if BL0939_V_RMS_EN
    #if BL0939_ELECT_USE_FLOAT
        if(Elect.Voltage_Value < 24)
        {
            *status = SWITCH_CLOSE;
        }
        else
        {
            *status = SWITCH_OPEN;
        }
    #else
        if(Elect.Voltage_Value < 240)
        {
            *status = SWITCH_CLOSE;
        }
        else
        {
            *status = SWITCH_OPEN;
        }
    #endif
#endif

    }
    else if(port_num == AISLE_DI1)
    {
        *status = !GpioRead( &MCU_DI1_obj );
    }
    else if(port_num == AISLE_DI2)
    {
        *status = !GpioRead( &MCU_DI2_obj );
    }
    else
    {
        drv_pwrDect_Get(&pwrDect_obj);
        switch (port_num) {
            case AISLE_220V_1:
                *status = !pwrDect_obj.v_Power_DECT3;
            break;
            case AISLE_220V_2:
                *status = !pwrDect_obj.v_Power_DECT2;
                break;
            case AISLE_220V_3:
                *status = !pwrDect_obj.v_Power_DECT1;
                break;
            case AISLE_220V_4:
                *status = !pwrDect_obj.v_Power_DECT4;
                break;
            case AISLE_220V_5:
                *status = !pwrDect_obj.v_Power_DECT5;
                break;
        default:
            break;
        }
    }
    return OK;
}

/**
 * @brief 设备温度获取
 * @param temperature 设备温度
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_temperature(float *temperature)
{
    if(NULL == temperature)
    {
        return ERROR_COM;
    }
    drv_pcuAdc_Get( &pcuAdc_obj );
    *temperature = pcuAdc_obj.V_TC;
    return OK;
}

/**
 * @brief 风扇、加热棒控制
 * @param dev_control     DEV_FAN 风扇  DEV_HEATER 加热棒
 * @param fan_status      SWITCH_CLOSE 关闭 SWITCH_OPEN 开启
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_fan_heater(uint8_t dev_control,uint8_t status)
{
    uint8_t i = 0;
    if(dev_control != DEV_FAN && dev_control != DEV_HEATER)
    {
        return ERROR_COM;
    }
    if (status > SWITCH_OPEN )
    {
        return ERROR_COM;
    }

    xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
    /* 直流回路 */
    for( i = 0 ; i < DIRECT_LOOP_LEN ; i++)
    {
        if(smart_power.direct_loop[i].dev_type == dev_control)
        {
            if(OK !=  app_control_switch_set(i + 1,status))
            {
                xSemaphoreGive(direct_loop_lock);
                return ERROR_COM;
            }
        }
    }
    xSemaphoreGive(direct_loop_lock);

    xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
    /* 交流回路 */
    for( i = 0 ; i < ALTERNATING_LOOP_LEN ; i++)
    {
        if(smart_power.alternating_loop[i].dev_type == dev_control)
        {
            if(OK !=  app_control_switch_set(i + 1 + AISLE_12V_485_2,status))
            {
                xSemaphoreGive(alternating_loop_lock);
                return ERROR_COM;
            }
        }
    }
    xSemaphoreGive(alternating_loop_lock);
    return OK;
}

/**
 * @brief 单灯调光控制
 * @param light_values_1    单灯1调光值
 * @param light_values_2    单灯2调光值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_single_light_set(uint8_t light_values_1,uint8_t light_values_2)
{
    uint8_t light_values_1_temp = 0;
    uint8_t light_values_2_temp = 0;
    if ((light_values_1 > MAX_LIGHT_VALUES && light_values_1 != LIGHT_NO_ACTION ) || (light_values_2 > MAX_LIGHT_VALUES && light_values_2 != LIGHT_NO_ACTION ))
    {
        return ERROR_COM;
    }
    if(light_values_1 == MIN_LIGHT_VALUES)
    {
        /* 关闭单灯1通道 */
        if(OK !=  app_control_light_switch_set(LIGHT_1_AISLE,SWITCH_CLOSE))
        {
            return ERROR_COM;            
        }
    }
    else if(light_values_1 != LIGHT_NO_ACTION)
    {
        /* 开启单灯1通道 */
        if(OK !=  app_control_light_switch_set(LIGHT_1_AISLE,SWITCH_OPEN))
        {
            return ERROR_COM;            
        }
    }

    if(light_values_2 == MIN_LIGHT_VALUES)
    {
        /* 关闭单灯2通道 */
        if(OK !=  app_control_light_switch_set(LIGHT_2_AISLE,SWITCH_CLOSE))
        {
            return ERROR_COM;            
        }
    }
    else if(light_values_2 != LIGHT_NO_ACTION)
    {
        /* 开启单灯2通道 */
        if(OK !=  app_control_light_switch_set(LIGHT_2_AISLE,SWITCH_OPEN))
        {
            return ERROR_COM;            
        }
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    if(light_values_1 == LIGHT_NO_ACTION)
    {
        light_values_1_temp = smart_power.switch_status.light_1;
    }
    else
    {
        light_values_1_temp = light_values_1;
    }

    if(light_values_2 == LIGHT_NO_ACTION)
    {
        light_values_2_temp = smart_power.switch_status.light_2;
    }
    else
    {
        light_values_2_temp = light_values_2;
    }    
    drv_pcuDac_Set(&pcuDac_obj,(float)light_values_1_temp/MAX_LIGHT_VALUES*MAX_DAC_VOLTAGE,(float)light_values_2_temp/MAX_LIGHT_VALUES*MAX_DAC_VOLTAGE);
    smart_power.switch_status.light_1 = light_values_1_temp;
    smart_power.switch_status.light_2 = light_values_2_temp;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 单灯调光值查询
 * @param light_values_1    单灯1调光值
 * @param light_values_2    单灯2调光值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_single_light_get(uint8_t *light_values_1,uint8_t *light_values_2)
{
    if(NULL == light_values_1 || NULL == light_values_2)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    *light_values_1 = smart_power.switch_status.light_1;
    *light_values_2 = smart_power.switch_status.light_2;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 氛围灯控制
 * @param ambient_mode  氛围灯模式
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_ambient_set(uint8_t ambient_mode)
{
    RGB_t tcolor[5];
    if(ambient_mode < AMBIENT_SINGLE_MODE || ambient_mode > AMBIENT_BLACK_MODE)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    smart_power.switch_status.ambient = ambient_mode;
    switch (ambient_mode) {
    case AMBIENT_SINGLE_MODE:
        tcolor[0].r = 255;
        tcolor[0].g = 0;
        tcolor[0].b = 0;
        tcolor[1].r = 0;
        tcolor[1].g = 0;
        tcolor[1].b = 0;
        led_set( &led_obj, &tcolor[0], 2, LED_WATER_MODE, 1000);
        break;
    case AMBIENT_COLOR_MODE:
        tcolor[0].r = 255;
        tcolor[0].g = 0;
        tcolor[0].b = 0;
        tcolor[1].r = 0;
        tcolor[1].g = 255;
        tcolor[1].b = 0;
        tcolor[2].r = 0;
        tcolor[2].g = 0;
        tcolor[2].b = 255;
        led_set( &led_obj, &tcolor[0], 3, LED_WATER_MODE, 300);
        break;
    case AMBIENT_BRIGHT_MODE:
        tcolor[0].r = 255;
        tcolor[0].g = 255;
        tcolor[0].b = 255;
        led_set( &led_obj, &tcolor[0], 1, LED_KEEP_MODE, 0 );
        break;
    case AMBIENT_BLACK_MODE:
        tcolor[0].r = 0;
        tcolor[0].g = 0;
        tcolor[0].b = 0;
        led_set( &led_obj, &tcolor[0], 1, LED_KEEP_MODE, 0 );
        break;
    default:
        break;
    }
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 氛围灯模式查询
 * @param ambient_mode  氛围灯模式
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_ambient_get(uint8_t * ambient_mode)
{
    if( NULL == ambient_mode)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    *ambient_mode = smart_power.switch_status.ambient;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 获取DI通道状态
 * @param DI1       DI1口状态
 * @param DI2       DI2口状态
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_DI(uint8_t *DI1, uint8_t *DI2)
{
    if(NULL == DI1 || NULL == DI2)
    {
        return ERROR_COM;
    }
    *DI1 = GpioRead( &MCU_DI1_obj );
    *DI2 = GpioRead( &MCU_DI2_obj );
    return OK;
}

/**
 * @brief 获取DI设备默认状态
 * @param dev_DI1       DI1口状态
 * @param dev_DI2       DI2口状态
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_DI_dev_status(uint8_t *dev_DI1, uint8_t *dev_DI2)
{
    if(NULL == dev_DI1 || NULL == dev_DI2)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    *dev_DI1 = smart_power.switch_status.DI_1;
    *dev_DI2 = smart_power.switch_status.DI_2;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 获取设备类型
 * @param DI_num        DI口编号
 * @param dev_type      设备类型
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_type(uint8_t aisle_num, uint8_t *dev_type)
{
    if(dev_type == NULL || aisle_num > AISLE_DI2 || aisle_num == 0)
    {
        return ERROR_COM;
    }
    
    if(aisle_num == AISLE_DI1)
    {
        xSemaphoreTake(switch_status_lock, portMAX_DELAY);
        *dev_type = smart_power.switch_status.DI_1_dev_type;
        xSemaphoreGive(switch_status_lock);
    }
    else if(aisle_num == AISLE_DI2)
    {
        xSemaphoreTake(switch_status_lock, portMAX_DELAY);
        *dev_type = smart_power.switch_status.DI_2_dev_type;
        xSemaphoreGive(switch_status_lock);
    }
    else if( aisle_num < AISLE_220V_1)
    {
        xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
        *dev_type = smart_power.direct_loop[aisle_num - 1].dev_type;
        xSemaphoreGive(direct_loop_lock);
    }
    else
    {
        xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
        *dev_type = smart_power.alternating_loop[aisle_num - AISLE_220V_1].dev_type;
        xSemaphoreGive(alternating_loop_lock);
    }
    return OK;
}

/**
 * @brief 获取直流回路电参数
 * @param direct_electricity        直流回路电参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_direct_electricity(DIRECT_ELECTRICITY_t *direct_electricity)
{
	uint8_t status = 0;
    if(NULL == direct_electricity)
    {
        return ERROR_COM;
    }
    drv_pcuAdc_Get(&pcuAdc_obj); 
    direct_electricity->V_24V = pcuAdc_obj.V_24V;
    direct_electricity->V_12V = pcuAdc_obj.V_12V;
    direct_electricity->I_12V_1 = pcuAdc_obj.I_12V_1;
    direct_electricity->I_12V_2 = pcuAdc_obj.I_12V_2;
    direct_electricity->I_12V_3 = pcuAdc_obj.I_12V_3;
    direct_electricity->I_24V = pcuAdc_obj.I_24V;
    direct_electricity->I_485_VCC1 = pcuAdc_obj.I_485_VCC2;
    direct_electricity->I_485_VCC2 = pcuAdc_obj.I_485_VCC1;
	
    xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
	if(app_control_switch_get( AISLE_24V ,&status) == OK && status)
	{
		if(smart_power.direct_loop[0].max_current == 0 || pcuAdc_obj.I_24V > smart_power.direct_loop[0].max_current)
		{
			smart_power.direct_loop[0].max_current = pcuAdc_obj.I_24V;
		}
		else if(smart_power.direct_loop[0].min_current == 0 || pcuAdc_obj.I_24V < smart_power.direct_loop[0].min_current)
		{
			smart_power.direct_loop[0].min_current = pcuAdc_obj.I_24V;
		}
	}
	
	if(app_control_switch_get( AISLE_12V_1 ,&status) == OK && status)
	{
		if(smart_power.direct_loop[1].max_current == 0 || pcuAdc_obj.I_12V_1 > smart_power.direct_loop[1].max_current)
		{
			smart_power.direct_loop[1].max_current = pcuAdc_obj.I_12V_1;
		}
		else if(smart_power.direct_loop[1].min_current == 0 || pcuAdc_obj.I_12V_1 < smart_power.direct_loop[1].min_current)
		{
			smart_power.direct_loop[1].min_current = pcuAdc_obj.I_12V_1;
		}
	}

	if(app_control_switch_get( AISLE_12V_2 ,&status) == OK && status)
	{
		if(smart_power.direct_loop[2].max_current == 0 || pcuAdc_obj.I_12V_2 > smart_power.direct_loop[2].max_current)
		{
			smart_power.direct_loop[2].max_current = pcuAdc_obj.I_12V_2;
		}
		else if(smart_power.direct_loop[2].min_current == 0 || pcuAdc_obj.I_12V_2 < smart_power.direct_loop[2].min_current)
		{
			smart_power.direct_loop[2].min_current = pcuAdc_obj.I_12V_2;
		}
	}
	
	if(app_control_switch_get( AISLE_12V_3 ,&status) == OK && status)
	{
		if(smart_power.direct_loop[3].max_current == 0 || pcuAdc_obj.I_12V_3 > smart_power.direct_loop[3].max_current)
		{
			smart_power.direct_loop[3].max_current = pcuAdc_obj.I_12V_3;
		}
		else if(smart_power.direct_loop[3].min_current == 0 || pcuAdc_obj.I_12V_3 < smart_power.direct_loop[3].min_current)
		{
			smart_power.direct_loop[3].min_current = pcuAdc_obj.I_12V_3;
		}
	}
	
	if(app_control_switch_get( AISLE_12V_485_2 ,&status) == OK && status)
	{
		if(smart_power.direct_loop[5].max_current == 0 || pcuAdc_obj.I_485_VCC1 > smart_power.direct_loop[5].max_current)
		{
			smart_power.direct_loop[5].max_current = pcuAdc_obj.I_485_VCC1;
		}
		else if(smart_power.direct_loop[5].min_current == 0 || pcuAdc_obj.I_485_VCC1 < smart_power.direct_loop[5].min_current)
		{
			smart_power.direct_loop[5].min_current = pcuAdc_obj.I_485_VCC1;
		}
	}

	if(app_control_switch_get( AISLE_12V_485_1 ,&status) == OK && status)
	{
		if(smart_power.direct_loop[4].max_current == 0 || pcuAdc_obj.I_485_VCC2 > smart_power.direct_loop[4].max_current)
		{
			smart_power.direct_loop[4].max_current = pcuAdc_obj.I_485_VCC2;
		}
		else if(smart_power.direct_loop[4].min_current == 0 || pcuAdc_obj.I_485_VCC2 < smart_power.direct_loop[4].min_current)
		{
			smart_power.direct_loop[4].min_current = pcuAdc_obj.I_485_VCC2;
		}
	}
    xSemaphoreGive(direct_loop_lock);
    return OK;
}

/**
 * @brief 监控主电源掉电状态
 * @param status
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_220v_main_loop_status(uint8_t * status)
{
    if(NULL == status)
    {
        return ERROR_COM;
    }
    drv_pwrDect_Get(&pwrDect_obj);
    *status = pwrDect_obj.v_BAT_CTRL;
    return OK;
}


/**
 * @brief 获取主电源电参数
 * @param communicat_loop
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_220v_main_loop_electricity(COMMUNICAT_LOOP_t * communicat_loop)
{
    if(NULL == communicat_loop)
    {
        return ERROR_COM;
    }
    Bl0939_Energy_t loop_energy;
    Bl0939_Elect_t  Elect;
    if(BSP_SUCCESS != Bl0939_GetEnergy(&bl0939_obj,&loop_energy))
    {
        return ERROR_COM;
    }
#if BL0939_CFB_EN
    #if BL0939_ELECT_USE_FLOAT
        communicat_loop->energy = loop_energy.Energy_B;
    #else
        communicat_loop->energy = (float)loop_energy.Energy_B/1000;
    #endif
#endif
    if(BSP_SUCCESS !=Bl0939_GetElect(&bl0939_obj,&Elect,BL0939_ELECT_ALL) )
    {
        return ERROR_COM;
    }
    drv_pwrDect_Get(&pwrDect_obj);
    communicat_loop->loop_status = pwrDect_obj.v_BAT_CTRL;
    
#if BL0939_V_RMS_EN
    #if BL0939_ELECT_USE_FLOAT
        communicat_loop->voltage = Elect.Voltage_Value;
    #else
        communicat_loop->voltage = (float)Elect.Voltage_Value/10;
    #endif
#endif

#if BL0939_IB_RMS_EN
    #if BL0939_ELECT_USE_FLOAT
        communicat_loop->current = Elect.Current_Value_B;
    #else
        communicat_loop->current = (float)Elect.Current_Value_B/1000;
    #endif
#endif
    
#if BL0939_B_WATT_EN
    #if BL0939_ELECT_USE_FLOAT
        communicat_loop->power_value = Elect.Power_Value_B;
    #else
        communicat_loop->power_value = (float)Elect.Power_Value_B/10;
    #endif
#endif
    if(communicat_loop->voltage != 0 && communicat_loop->current != 0)
    {
        communicat_loop->power_factor = communicat_loop->power_value/communicat_loop->voltage/communicat_loop->current;
    }
    else
    {
        communicat_loop->power_factor = 0;
    }
    
    return OK;
}

/**
 * @brief 获取单灯回路电参数
 * @param communicat_loop
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_220v_light_loop_electricity(LIGHT_LOOP_t * light_loop)
{
    if(NULL == light_loop)
    {
        return ERROR_COM;
    }
    Bl0906_Elect_t Elect;
    Bl0906_Energy_t Bl0906_energy;
    if(BSP_SUCCESS!= Bl0906_GetElect(&bl0906_obj,&Elect,BL0906_ELECT_I_1|BL0906_ELECT_I_2|BL0906_ELECT_V|BL0906_ELECT_P_1|BL0906_ELECT_P_2))
    {
        return ERROR_COM;
    }

#if BL0906_V_RMS_EN
    #if BL0906_ELECT_USE_FLOAT
        light_loop->voltage = Elect.RMS_V;
    #else
        light_loop->voltage = (float)Elect.RMS_V/10;
    #endif
#endif

#if BL0906_2_RMS_EN
    #if BL0906_ELECT_USE_FLOAT
        light_loop->current = Elect.RMS_1 + Elect.RMS_2;
    #else
        light_loop->current = (float)Elect.RMS_1/1000 + (float)Elect.RMS_2/1000;
    #endif
#endif

#if BL0906_WATT1_EN && BL0906_WATT2_EN
    #if BL0906_ELECT_USE_FLOAT
        light_loop->power_value = Elect.WATT_1 + Elect.WATT_2;
    #else
        light_loop->power_value = (float)Elect.WATT_1/10 + (float)Elect.WATT_2/10;
    #endif
#endif

    if(light_loop->voltage != 0 && light_loop->current != 0)
    {
        light_loop->power_factor = light_loop->power_value/light_loop->voltage/light_loop->current;
    }
    else
    {
        light_loop->power_factor = 0;
    }
    if(BSP_SUCCESS != Bl0906_GetEnergy(&bl0906_obj,&Bl0906_energy))
    {
        return ERROR_COM;
    }
#if BL0906_CF1_EN && BL0906_CF2_EN
    #if BL0906_ELECT_USE_FLOAT
        light_loop->energy = Bl0906_energy.Energy_1 + Bl0906_energy.Energy_2;
    #else
        light_loop->energy = (float)Bl0906_energy.Energy_1/1000 + (float)Bl0906_energy.Energy_2/1000;
    #endif
#endif
    
    return OK;
}

/**
 * @brief 获取220V支路电参数
 * @param leakage
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_220v_branch_loop_electricity(BRANCH_220V_LOOP_t * branch_220V_loop)
{
    if(NULL == branch_220V_loop)
    {
        return ERROR_COM;
    }
    Bl0906_Elect_t Elect;
    Bl0939_Elect_t Elect_0939;
    if(BSP_SUCCESS!= Bl0906_GetElect(&bl0906_obj,&Elect,BL0906_ELECT_I_1|BL0906_ELECT_I_2|BL0906_ELECT_I_3|BL0906_ELECT_I_4|BL0906_ELECT_I_5|BL0906_ELECT_V|BL0906_ELECT_P_1|BL0906_ELECT_P_2))
    {
        return ERROR_COM;
    }
    
    if(BSP_SUCCESS != Bl0939_GetElect(&bl0939_obj,&Elect_0939,BL0939_ELECT_V))
    {
        return ERROR_COM;
    }

#if BL0939_V_RMS_EN
    #if BL0939_ELECT_USE_FLOAT
        branch_220V_loop->voltage = Elect_0939.Voltage_Value;
    #else
        communicat_loop->voltage = (float)Elect.Voltage_Value/10;
    #endif
#endif

#if BL0906_5_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->loop_1_current = Elect.RMS_5;
    #else
        branch_220V_loop->loop_1_current = (float)Elect.RMS_5/1000;
    #endif
#endif

#if BL0906_4_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->loop_2_current = Elect.RMS_4;
    #else
        branch_220V_loop->loop_2_current = (float)Elect.RMS_4/1000;
    #endif
#endif
    
#if BL0906_3_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->loop_3_current = Elect.RMS_3;
    #else
        branch_220V_loop->loop_3_current = (float)Elect.RMS_3/1000;
    #endif
#endif

#if BL0906_1_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->loop_4_current = Elect.RMS_1;
    #else
        branch_220V_loop->loop_4_current = (float)Elect.RMS_1/1000;
    #endif
#endif

#if BL0906_2_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->loop_5_current = Elect.RMS_2;
    #else
        branch_220V_loop->loop_5_current = (float)Elect.RMS_2/1000;
    #endif
#endif
    
#if BL0906_WATT1_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->light1_power = Elect.WATT_1;
    #else
        branch_220V_loop->light1_power = (float)Elect.WATT_1/10;
    #endif
#endif   

#if BL0906_WATT2_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->light2_power = Elect.WATT_2;
    #else
        branch_220V_loop->light2_power = (float)Elect.WATT_2/10;
    #endif
#endif 

#if BL0906_V_RMS_EN 
    #if BL0906_ELECT_USE_FLOAT
        branch_220V_loop->light_voltage = Elect.RMS_V;
    #else
        branch_220V_loop->voltage = (float)Elect.RMS_V/10;
    #endif
#endif 

    drv_pwrDect_Get(&pwrDect_obj);
    branch_220V_loop->loop_1_status = pwrDect_obj.v_Power_DECT3;
    branch_220V_loop->loop_2_status = pwrDect_obj.v_Power_DECT2;
    branch_220V_loop->loop_3_status = pwrDect_obj.v_Power_DECT1;
    branch_220V_loop->loop_4_status = pwrDect_obj.v_Power_DECT4;
    branch_220V_loop->loop_5_status = pwrDect_obj.v_Power_DECT5;
    #if BL0906_ELECT_USE_FLOAT
    if(!branch_220V_loop->loop_1_status)
    {
        if(smart_power.alternating_loop[0].max_current == 0 || (float)Elect.RMS_5 > smart_power.alternating_loop[0].max_current)
        {
            smart_power.alternating_loop[0].max_current = (float)Elect.RMS_5;
        }
        else if(smart_power.alternating_loop[0].min_current == 0 || (float)Elect.RMS_5 < smart_power.alternating_loop[0].min_current)
        {
            smart_power.alternating_loop[0].min_current = (float)Elect.RMS_5;
        }
    }

	if(!branch_220V_loop->loop_2_status)
	{
		if(smart_power.alternating_loop[1].max_current == 0 || (float)Elect.RMS_4 > smart_power.alternating_loop[1].max_current)
		{
			smart_power.alternating_loop[1].max_current = (float)Elect.RMS_4;
		}
		else if(smart_power.alternating_loop[1].min_current == 0 || (float)Elect.RMS_4 < smart_power.alternating_loop[1].min_current)
		{
			smart_power.alternating_loop[1].min_current = (float)Elect.RMS_4;
		}
	}
	
	if(!branch_220V_loop->loop_3_status)
	{
		if(smart_power.alternating_loop[2].max_current == 0 || (float)Elect.RMS_3 > smart_power.alternating_loop[2].max_current)
		{
			smart_power.alternating_loop[2].max_current = (float)Elect.RMS_3;
		}
		else if(smart_power.alternating_loop[2].min_current == 0 || (float)Elect.RMS_3 < smart_power.alternating_loop[2].min_current)
		{
			smart_power.alternating_loop[2].min_current = (float)Elect.RMS_3;
		}
	}
	
	if(!branch_220V_loop->loop_4_status)
	{
		if(smart_power.alternating_loop[3].max_current == 0 || (float)Elect.RMS_1 > smart_power.alternating_loop[3].max_current)
		{
			smart_power.alternating_loop[3].max_current = (float)Elect.RMS_1;
		}
		else if(smart_power.alternating_loop[3].min_current == 0 || (float)Elect.RMS_1 < smart_power.alternating_loop[3].min_current)
		{
			smart_power.alternating_loop[3].min_current = (float)Elect.RMS_1;
		}
	}

	if(!branch_220V_loop->loop_5_status)
	{
		if(smart_power.alternating_loop[4].max_current == 0 || (float)Elect.RMS_2 > smart_power.alternating_loop[4].max_current)
		{
			smart_power.alternating_loop[4].max_current = (float)Elect.RMS_2;
		}
		else if(smart_power.alternating_loop[4].min_current == 0 || (float)Elect.RMS_2 < smart_power.alternating_loop[4].min_current)
		{
			smart_power.alternating_loop[4].min_current = (float)Elect.RMS_2;
		}
	}
#else
    if(!branch_220V_loop->loop_1_status)
    {
        if(smart_power.alternating_loop[0].max_current == 0 || (float)Elect.RMS_5/1000 > smart_power.alternating_loop[0].max_current)
        {
            smart_power.alternating_loop[0].max_current = (float)Elect.RMS_5/1000;
        }
        else if(smart_power.alternating_loop[0].min_current == 0 || (float)Elect.RMS_5/1000 < smart_power.alternating_loop[0].min_current)
        {
            smart_power.alternating_loop[0].min_current = (float)Elect.RMS_5/1000;
        }
    }

	if(!branch_220V_loop->loop_2_status)
	{
		if(smart_power.alternating_loop[1].max_current == 0 || (float)Elect.RMS_4/1000 > smart_power.alternating_loop[1].max_current)
		{
			smart_power.alternating_loop[1].max_current = (float)Elect.RMS_4/1000;
		}
		else if(smart_power.alternating_loop[1].min_current == 0 || (float)Elect.RMS_4/1000 < smart_power.alternating_loop[1].min_current)
		{
			smart_power.alternating_loop[1].min_current = (float)Elect.RMS_4/1000;
		}
	}
	
	if(!branch_220V_loop->loop_3_status)
	{
		if(smart_power.alternating_loop[2].max_current == 0 || (float)Elect.RMS_3/1000 > smart_power.alternating_loop[2].max_current)
		{
			smart_power.alternating_loop[2].max_current = (float)Elect.RMS_3/1000;
		}
		else if(smart_power.alternating_loop[2].min_current == 0 || (float)Elect.RMS_3/1000 < smart_power.alternating_loop[2].min_current)
		{
			smart_power.alternating_loop[2].min_current = (float)Elect.RMS_3/1000;
		}
	}
	
	if(!branch_220V_loop->loop_4_status)
	{
		if(smart_power.alternating_loop[3].max_current == 0 || (float)Elect.RMS_1/1000 > smart_power.alternating_loop[3].max_current)
		{
			smart_power.alternating_loop[3].max_current = (float)Elect.RMS_1/1000;
		}
		else if(smart_power.alternating_loop[3].min_current == 0 || (float)Elect.RMS_1/1000 < smart_power.alternating_loop[3].min_current)
		{
			smart_power.alternating_loop[3].min_current = (float)Elect.RMS_1/1000;
		}
	}

	if(!branch_220V_loop->loop_5_status)
	{
		if(smart_power.alternating_loop[4].max_current == 0 || (float)Elect.RMS_2/1000 > smart_power.alternating_loop[4].max_current)
		{
			smart_power.alternating_loop[4].max_current = (float)Elect.RMS_2/1000;
		}
		else if(smart_power.alternating_loop[4].min_current == 0 || (float)Elect.RMS_2/1000 < smart_power.alternating_loop[4].min_current)
		{
			smart_power.alternating_loop[4].min_current = (float)Elect.RMS_2/1000;
		}
	}
#endif
    return OK;
}

/**
 * @brief 获取心跳上报周期
 * @param heart       相对与X轴的倾角
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_heart_get(uint16_t * heart)
{
    if(NULL == heart)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(info_lock, portMAX_DELAY);
    *heart = smart_power.info.heartbeat;
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 获取倾角参数
 * @param angle_x       相对与X轴的倾角
 * @param angle_y       相对与Y轴的倾角
 * @param angle_z       相对与Z轴的倾角
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_tilt(float *angle_x, float *angle_y, float *angle_z)
{
    uint8_t out_send;
    uint16_t offset = 0;
    uint8_t rev_buffer[MAX_485_RECV];
    uint16_t receive_len = 0;
    if(NULL == angle_x || NULL == angle_y || NULL == angle_z)
    {
        return ERROR_COM;
    }
    memset(rev_buffer,0,MAX_485_RECV);
    if(OK != Msc_Send(MSC_INTEL,GET_TILT_CODE,&out_send,0,(uint8_t *)rev_buffer,&receive_len))
    {
        /*  */
        return ERROR_COM;
    }
    POUT_STORE_FLOAT(rev_buffer,*angle_x,offset);
    POUT_STORE_FLOAT(rev_buffer,*angle_y,offset);
    POUT_STORE_FLOAT(rev_buffer,*angle_z,offset);
    return OK;
}

/**
 * @brief 倾斜监控任务获取参数
 * @param tilt_task       倾斜监控任务结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_tilt_task_get(TILT_TASK_t *tilt_task)
{
    if(NULL == tilt_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    tilt_task->tilt = smart_power.threshold.tilt_task_values.tilt;
    tilt_task->tilt_x = smart_power.threshold.tilt_task_values.tilt_x;
    tilt_task->tilt_y = smart_power.threshold.tilt_task_values.tilt_y;
    tilt_task->tilt_z = smart_power.threshold.tilt_task_values.tilt_z;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 漏电监测任务参数获取接口
 * @param leakage_task  漏电任务结构体
 */
int32_t app_control_leakage_task_get(LEAKAGE_TASK_t *leakage_task)
{
    if(NULL == leakage_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    leakage_task->leakage_enable = smart_power.threshold.leakage_task_values.leakage_enable;
    leakage_task->leakage_frequency = smart_power.threshold.leakage_task_values.leakage_frequency;
    leakage_task->leakage_times = smart_power.threshold.leakage_task_values.leakage_times;
    leakage_task->leakage_values = smart_power.threshold.leakage_task_values.leakage_values;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 温度监测任务参数获取接口
 * @param temperature_task
 */
int32_t app_control_temperature_task_get(TEMPERATURE_TASK_t *temperature_task)
{
    if(NULL == temperature_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    temperature_task->temperature_enable = smart_power.threshold.temperature_task_values.temperature_enable;
    temperature_task->fan_temperature = smart_power.threshold.temperature_task_values.fan_temperature;
    temperature_task->heater_temperature = smart_power.threshold.temperature_task_values.heater_temperature;
    temperature_task->high_temperature = smart_power.threshold.temperature_task_values.high_temperature;
    temperature_task->low_temperature = smart_power.threshold.temperature_task_values.low_temperature;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 弱电任务参数获取接口
 * @param weak_current_task
 */
int32_t app_control_weak_current_task_get(WEAK_CURRENT_TASK_t *weak_current_task)
{
    if(NULL == weak_current_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    weak_current_task->direct_high_current = smart_power.threshold.weak_current_task_values.direct_high_current;
    weak_current_task->direct_12V_high_voltage = smart_power.threshold.weak_current_task_values.direct_12V_high_voltage;
    weak_current_task->direct_12V_low_voltage = smart_power.threshold.weak_current_task_values.direct_12V_low_voltage;
    weak_current_task->direct_24V_high_voltage = smart_power.threshold.weak_current_task_values.direct_24V_high_voltage;
    weak_current_task->direct_24V_low_voltage = smart_power.threshold.weak_current_task_values.direct_24V_low_voltage;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 强电任务参数获取接口
 * @param strong_current_task
 */
int32_t app_control_strong_current_task_get(STRONG_CURRENT_TASK_t *strong_current_task)
{
    if(NULL == strong_current_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    strong_current_task->alternating_high_current = smart_power.threshold.strong_current_task_values.alternating_high_current;
    strong_current_task->alternating_high_voltage = smart_power.threshold.strong_current_task_values.alternating_high_voltage;
    strong_current_task->alternating_low_voltage = smart_power.threshold.strong_current_task_values.alternating_low_voltage;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 配置漏电阈值与重试次数
 * @param leakage_values    漏电阈值
 * @param leakage_times     漏电重试次数
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_leakage_threshold_set(uint16_t leakage_values, uint8_t leakage_times,uint8_t leakage_long)
{
    if(leakage_times == 0 || leakage_times > LEAKAGE_RETRY_MAX_TIMRE || leakage_long < LEAKAGE_LONG_MIN_TIMRE || leakage_long > LEAKAGE_LONG_MAX_TIMRE || leakage_values < LEAKAGE_VALUES_MIN || leakage_values > LEAKAGE_VALUES_MAX)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    smart_power.threshold.leakage_task_values.leakage_values = leakage_values;
    smart_power.threshold.leakage_task_values.leakage_frequency = leakage_times;
    smart_power.threshold.leakage_task_values.leakage_times = leakage_long;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 获取漏电阈值与重试次数
 * @param leakage_values    漏电阈值
 * @param leakage_times     漏电重试次数
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_leakage_threshold_get(uint16_t *leakage_values, uint8_t *leakage_times,uint8_t *leakage_long)
{
    if(NULL == leakage_values || NULL == leakage_times)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    *leakage_values = (uint16_t)smart_power.threshold.leakage_task_values.leakage_values;
    *leakage_times = smart_power.threshold.leakage_task_values.leakage_frequency;
    *leakage_long = smart_power.threshold.leakage_task_values.leakage_times;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 配置高低温阈值
 * @param high_temperature    高温阈值
 * @param low_temperature     低温阈值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_temperature_threshold_set(float high_temperature, float low_temperature)
{
    if(high_temperature <= low_temperature || high_temperature > MAX_TEMPERATURE || low_temperature < MIN_TEMPERATURE)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    smart_power.threshold.temperature_task_values.high_temperature = high_temperature;
    smart_power.threshold.temperature_task_values.low_temperature = low_temperature;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 获取高低温阈值
 * @param high_temperature    高温阈值
 * @param low_temperature     低温阈值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_temperature_threshold_get(float *high_temperature, float *low_temperature)
{
    if(NULL == high_temperature || NULL == low_temperature)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    *high_temperature = smart_power.threshold.temperature_task_values.high_temperature;
    *low_temperature = smart_power.threshold.temperature_task_values.low_temperature;
    xSemaphoreGive(threshold_lock);
    return OK;
}


/**
 * @brief 配置风扇、加热棒阈值
 * @param fan_temperature    风扇阈值
 * @param heater_temperature 加热棒阈值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_fan_heater_threshold_set(float fan_temperature, float heater_temperature)
{
    if(fan_temperature - heater_temperature < MIN_FAN_HEARTER_TEMPERATURE || fan_temperature > MAX_TEMPERATURE || heater_temperature < MIN_TEMPERATURE)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    smart_power.threshold.temperature_task_values.fan_temperature = fan_temperature;
    smart_power.threshold.temperature_task_values.heater_temperature = heater_temperature;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 获取风扇、加热棒阈值
 * @param fan_temperature    风扇阈值
 * @param heater_temperature 加热棒阈值
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_fan_heater_threshold_get(float *fan_temperature, float *heater_temperature)
{
    if(NULL == fan_temperature || NULL == heater_temperature)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    *fan_temperature = smart_power.threshold.temperature_task_values.fan_temperature;
    *heater_temperature = smart_power.threshold.temperature_task_values.heater_temperature;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 配置倾斜初值及告警阈值
 * @param tilt_task 倾斜参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_tilt_threshold_set(TILT_TASK_t tilt_task)
{
    if(tilt_task.tilt_x > MAX_TILT || tilt_task.tilt_x < MIN_TILT || tilt_task.tilt_y > MAX_TILT || tilt_task.tilt_y < MIN_TILT || tilt_task.tilt_z > MAX_TILT || tilt_task.tilt_z < MIN_TILT || tilt_task.tilt > MAX_TILT || tilt_task.tilt < MIN_TILT)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    smart_power.threshold.tilt_task_values.tilt_x = tilt_task.tilt_x;
    smart_power.threshold.tilt_task_values.tilt_y = tilt_task.tilt_y;
    smart_power.threshold.tilt_task_values.tilt_z = tilt_task.tilt_z;
    smart_power.threshold.tilt_task_values.tilt = tilt_task.tilt;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 配置倾斜初值及告警阈值
 * @param tilt_task 倾斜参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_tilt_threshold_get(TILT_TASK_t *tilt_task)
{
    if(NULL == tilt_task)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    tilt_task->tilt_x = smart_power.threshold.tilt_task_values.tilt_x;
    tilt_task->tilt_y = smart_power.threshold.tilt_task_values.tilt_y;
    tilt_task->tilt_z = smart_power.threshold.tilt_task_values.tilt_z;
    tilt_task->tilt = smart_power.threshold.tilt_task_values.tilt;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 获取空闲单灯任务编号
 * @param plan_type 计划类型
 * @param plan_num 任务编号
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
static int32_t app_control_free_plan_get(uint8_t plan_type , uint8_t *plan_num)
{
    uint8_t i = 0;

    if(plan_type == PLAN_TYPE_LIGHT)
    {
        for( i = 0 ; i < LIGHT_PLAN_MAX_NUM ; i++)
        {
            if(smart_power.plan_arr[i].plan_type != PLAN_TYPE_LIGHT)
            {
                break;
            }
        }
        log_i(" app_control_free_plan_get %d \r\n ",i);
        if(i == LIGHT_PLAN_MAX_NUM)
        {
            *plan_num = 0;
            return ERROR_COM;
        }
        *plan_num = i;
        return OK;
    }
    else if(plan_type == PLAN_TYPE_AMBIENT)
    {
        for( i = 0 ; i < AMBIENT_PLAN_MAX_NUM ; i++)
        {
            if(smart_power.plan_arr[i + LIGHT_PLAN_MAX_NUM].plan_type == 0)
            {
                break;
            }
        }
        if(i == AMBIENT_PLAN_MAX_NUM)
        {
            *plan_num = 0;
            return ERROR_COM;
        }
        *plan_num = i + LIGHT_PLAN_MAX_NUM;
        return OK;
    }
    else
    {
        return ERROR_COM;
    }
}

/**
 * @brief 新增计划
 * @param plan_values 计划参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_plan_add(PLAN_VALUES_t * plan_values)
{
    uint8_t plan_num = 0;
    xSemaphoreTake(plan_lock, portMAX_DELAY);
    if(OK !=  app_control_free_plan_get(plan_values->plan_type,&plan_num))
    {
        xSemaphoreGive(plan_lock);
        return ERROR_COM;
    }
    smart_power.plan_arr[plan_num].plan_type = plan_values->plan_type;
    smart_power.plan_arr[plan_num].light_num = plan_values->light_num;
    smart_power.plan_arr[plan_num].light_values = plan_values->light_values;
    smart_power.plan_arr[plan_num].work_time = plan_values->work_time;
    smart_power.plan_arr[plan_num].ambient_type = plan_values->ambient_type;
    xSemaphoreGive(plan_lock);
    return OK;
}

/**
 * @brief 删除计划
 * @param plan_num 单灯计划编号
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_plan_del(uint8_t plan_num )
{
    if(plan_num == 0 || plan_num > LIGHT_PLAN_MAX_NUM + AMBIENT_PLAN_MAX_NUM)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(plan_lock, portMAX_DELAY);
    smart_power.plan_arr[plan_num - 1].plan_type = PLAN_TYPE_NULL;
    smart_power.plan_arr[plan_num - 1].light_num = 0;
    smart_power.plan_arr[plan_num - 1].light_values = 0;
    smart_power.plan_arr[plan_num - 1].work_time = 0;
    smart_power.plan_arr[plan_num - 1].ambient_type = 0;
    xSemaphoreGive(plan_lock);
    return OK;
}

/**
 * @brief 查询计划
 * @param plan_num      计划编号
 * @param plan_values   计划参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_plan_sel(uint8_t plan_num ,PLAN_VALUES_t *plan_values)
{
    if((plan_num >= (uint8_t)(LIGHT_PLAN_MAX_NUM + AMBIENT_PLAN_MAX_NUM)) || (NULL == plan_values))
    {
        return ERROR_COM;
    }
    xSemaphoreTake(plan_lock, portMAX_DELAY);
    plan_values->plan_type = smart_power.plan_arr[plan_num].plan_type;
    plan_values->light_num = smart_power.plan_arr[plan_num].light_num;
    plan_values->light_values = smart_power.plan_arr[plan_num].light_values;
    plan_values->work_time = smart_power.plan_arr[plan_num].work_time;
    plan_values->ambient_type = smart_power.plan_arr[plan_num].ambient_type;
    xSemaphoreGive(plan_lock);
    return OK;
}

/**
 * @brief 配置设备映射
 * @param info_num 通道号
 * @param dev_type 设备类型
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_map_set(uint8_t info_num ,uint8_t dev_type)
{
    if(info_num == 0 || info_num > AISLE_DI2 || dev_type > DEV_LIGHTNING_PROTECTOR )
    {
        return ERROR_COM;
    }
    if(info_num <= AISLE_12V_485_2)
    {
        xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
        smart_power.direct_loop[info_num - AISLE_24V].dev_type = dev_type;
        smart_power.direct_loop[info_num - AISLE_24V].max_current = 0;
        smart_power.direct_loop[info_num - AISLE_24V].min_current = 0;
        xSemaphoreGive(direct_loop_lock);
    }
    else if(info_num <= AISLE_220V_5)
    {
        xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
        smart_power.alternating_loop[info_num - AISLE_220V_1].dev_type = dev_type;
        smart_power.alternating_loop[info_num - AISLE_220V_1].max_current = 0;
        smart_power.alternating_loop[info_num - AISLE_220V_1].min_current = 0;
        xSemaphoreGive(alternating_loop_lock);
    }
    else
    {
        xSemaphoreTake(switch_status_lock, portMAX_DELAY);
        if(info_num - AISLE_220V_5 == 1)
        {
            smart_power.switch_status.DI_1_dev_type = dev_type;
        }
        else
        {
            smart_power.switch_status.DI_2_dev_type = dev_type;
        }
        xSemaphoreGive(switch_status_lock);
    }
    return OK;
}

/**
 * @brief 获取设备映射
 * @param info_num 通道号
 * @param dev_type 设备类型
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_map_get(uint8_t info_num ,uint8_t *dev_type)
{
    if(info_num == 0 || info_num > AISLE_DI2 || dev_type  == NULL)
    {
        return ERROR_COM;
    }

    if(info_num <= DIRECT_LOOP_LEN)
    {
        xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
        *dev_type = smart_power.direct_loop[info_num - 1].dev_type;
        xSemaphoreGive(direct_loop_lock);
    }
    else if(info_num <= ALTERNATING_LOOP_LEN + DIRECT_LOOP_LEN)
    {
        xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
        *dev_type = smart_power.alternating_loop[info_num - 1 - DIRECT_LOOP_LEN].dev_type;
        xSemaphoreGive(alternating_loop_lock);
    }
    else
    {
        xSemaphoreTake(switch_status_lock, portMAX_DELAY);
        if(info_num - AISLE_220V_5 == 1)
        {
            *dev_type = smart_power.switch_status.DI_1_dev_type;
        }
        else
        {
            *dev_type = smart_power.switch_status.DI_2_dev_type;
        }
        xSemaphoreGive(switch_status_lock);
    }
    return OK;    
}

/**
 * @brief 设置设备信息
 * @param dev_info 设备信息结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_info_set(INFO_t dev_info)
{
    xSemaphoreTake(info_lock, portMAX_DELAY);
    memcpy(smart_power.info.dev_name,dev_info.dev_name,DEV_NAME_LEN);
    memcpy(smart_power.info.pole_num,dev_info.pole_num,POLE_NUM);
    memcpy(smart_power.info.longitude,dev_info.longitude,LONGITUDE_LEN);
    memcpy(smart_power.info.latitude,dev_info.latitude,LATITUDE_LEN);
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 获取设备信息
 * @param dev_info 设备信息结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_info_get(INFO_t *dev_info)
{
    if(NULL == dev_info)
    {   
        return ERROR_COM;
    }
    xSemaphoreTake(info_lock, portMAX_DELAY);
    memcpy(dev_info->dev_name,smart_power.info.dev_name,DEV_NAME_LEN);
    memcpy(dev_info->pole_num,smart_power.info.pole_num,POLE_NUM);
    memcpy(dev_info->longitude,smart_power.info.longitude,LONGITUDE_LEN);
    memcpy(dev_info->latitude,smart_power.info.latitude,LATITUDE_LEN);
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 设置设备网络信息
 * @param dev_net 设备网络参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_net_set(NET_t dev_net)
{
    wiz_NetInfo net_info;
    memset(&net_info,0,sizeof(wiz_NetInfo));
    memcpy(net_info.ip,dev_net.ip,NET_ARR_LEN);
    memcpy(net_info.sn,dev_net.mask,NET_ARR_LEN);
    memcpy(net_info.gw,dev_net.gateway,NET_ARR_LEN);
    if(OK != Msc_Tcp_Local_Set(&net_info))
    {
        return ERROR_COM;
    }
    xSemaphoreTake(net_lock, portMAX_DELAY);
    memcpy(smart_power.net.ip,dev_net.ip,NET_ARR_LEN);
    memcpy(smart_power.net.mask,dev_net.mask,NET_ARR_LEN);
    memcpy(smart_power.net.gateway,dev_net.gateway,NET_ARR_LEN);
    xSemaphoreGive(net_lock);
    return OK;
}


/**
 * @brief 获取设备网络信息
 * @param dev_net 设备网络参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_net_get(NET_t *dev_net)
{
    if(NULL == dev_net)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(net_lock, portMAX_DELAY);
    memcpy(dev_net->ip,smart_power.net.ip,NET_ARR_LEN);
    memcpy(dev_net->mask,smart_power.net.mask,NET_ARR_LEN);
    memcpy(dev_net->gateway,smart_power.net.gateway,NET_ARR_LEN);
    xSemaphoreGive(net_lock);
    return OK;
}

/**
 * @brief 设置设备平台连接信息
 * @param dev_north_connect 设备平台连接参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_north_connect_set(NORTH_CONNECT_t dev_north_connect)
{
    if(OK != Msc_Tcp_Remote_Set(dev_north_connect.ip,dev_north_connect.port,NULL))
    {
        return ERROR_COM;
    }
    xSemaphoreTake(net_lock, portMAX_DELAY);
    memcpy(smart_power.north_connect.ip,dev_north_connect.ip,NET_ARR_LEN);
    smart_power.north_connect.port = dev_north_connect.port;
    xSemaphoreGive(net_lock);
    return OK;
}


/**
 * @brief 获取设备平台连接信息
 * @param dev_north_connect 设备平台连接参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_north_connect_get(NORTH_CONNECT_t *dev_north_connect)
{
    if(NULL == dev_north_connect)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(net_lock, portMAX_DELAY);
    memcpy(dev_north_connect->ip,smart_power.north_connect.ip,NET_ARR_LEN);
    dev_north_connect->port = smart_power.north_connect.port;
    xSemaphoreGive(net_lock);
    return OK;
}

/**
 * @brief 设置设备485口信息
 * @param serial_num 串口编号
 * @param serial_485 串口参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_485_set(uint8_t serial_num ,SERIAL_485_t serial_485)
{
    if(OK != Msc_485_Set(serial_num, serial_485.baudrate, serial_485.databit, serial_485.stopbit, serial_485.parity, serial_485.flowctl))
    {
        return ERROR_COM;
    }
    xSemaphoreTake(serial_lock, portMAX_DELAY);
    if(serial_num == SERIAL_485_1)
    {
        smart_power.serial_1.baudrate = serial_485.baudrate;
        smart_power.serial_1.databit = serial_485.databit;
        smart_power.serial_1.stopbit = serial_485.stopbit;
        smart_power.serial_1.parity = serial_485.parity;
        smart_power.serial_1.flowctl = serial_485.flowctl;
        /* 配置生效 */
    }
    else if(serial_num == SERIAL_485_2)
    {
        smart_power.serial_2.baudrate = serial_485.baudrate;
        smart_power.serial_2.databit = serial_485.databit;
        smart_power.serial_2.stopbit = serial_485.stopbit;
        smart_power.serial_2.parity = serial_485.parity;
        smart_power.serial_2.flowctl = serial_485.flowctl;
        /* 配置生效 */
    }
    else
    {
        xSemaphoreGive(serial_lock);
        return ERROR_COM;
    }
    xSemaphoreGive(serial_lock);
    return OK;
}

/**
 * @brief 获取设备485口信息
 * @param serial_num 串口编号
 * @param serial_485 串口参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_485_get(uint8_t serial_num ,SERIAL_485_t *serial_485)
{
    if(NULL == serial_485)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(serial_lock, portMAX_DELAY);
    if(serial_num == SERIAL_485_1)
    {
        serial_485->baudrate = smart_power.serial_1.baudrate;
        serial_485->databit = smart_power.serial_1.databit;
        serial_485->stopbit = smart_power.serial_1.stopbit;
        serial_485->parity = smart_power.serial_1.parity;
        serial_485->flowctl = smart_power.serial_1.flowctl;
    }
    else if(serial_num == SERIAL_485_2)
    {
        serial_485->baudrate = smart_power.serial_2.baudrate;
        serial_485->databit = smart_power.serial_2.databit;
        serial_485->stopbit = smart_power.serial_2.stopbit;
        serial_485->parity = smart_power.serial_2.parity;
        serial_485->flowctl = smart_power.serial_2.flowctl;
    }
    else
    {
        xSemaphoreGive(serial_lock);
        return ERROR_COM;
    }
    xSemaphoreGive(serial_lock);
    return OK;

}

/**
 * @brief 设置心跳上报周期
 * @param heart       心跳周期(s)
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_heart_set(uint16_t  heart)
{
    if(heart > MAX_HEARTBEAT || heart < MIN_HEARTBEAT )
    {
        return ERROR_COM;
    }
    xSemaphoreTake(info_lock, portMAX_DELAY);
    smart_power.info.heartbeat = heart;
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 设置高低温、漏电告警动作标志
 * @param temperature_flag  高低温动作
 * @param leakage_flag      漏电动作标志
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_temperature_leakage_set(uint8_t temperature_flag,uint8_t leakage_flag)
{
    if(leakage_flag > LEAKAGE_ALARM_REPORT || leakage_flag == 0 || temperature_flag > 1)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    smart_power.threshold.temperature_task_values.temperature_enable = temperature_flag;
    smart_power.threshold.leakage_task_values.leakage_enable = leakage_flag;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 获取高低温、漏电告警动作标志
 * @param heart       心跳周期(s)
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_temperature_leakage_get(uint8_t *temperature_flag,uint8_t *leakage_flag)
{
    if(NULL == leakage_flag || NULL == temperature_flag)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(threshold_lock, portMAX_DELAY);
    *temperature_flag = smart_power.threshold.temperature_task_values.temperature_enable;
    *leakage_flag = smart_power.threshold.leakage_task_values.leakage_enable;
    xSemaphoreGive(threshold_lock);
    return OK;
}

/**
 * @brief 设置di设备初始状态
 * @param DI1_flag      DI1口设备初始状态
 * @param DI2_flag      DI2口设备初始状态
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_DI_flag_set(uint8_t DI1_flag,uint8_t DI2_flag)
{
    if(DI1_flag > 1 || DI2_flag > 1)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    smart_power.switch_status.DI_1 = DI1_flag;
    smart_power.switch_status.DI_2 = DI2_flag;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 查询di设备初始状态
 * @param DI1_flag      DI1口设备初始状态
 * @param DI2_flag      DI2口设备初始状态
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_DI_flag_get(uint8_t *DI1_flag,uint8_t *DI2_flag)
{
    if(NULL == DI1_flag || NULL == DI2_flag )
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    *DI1_flag = smart_power.switch_status.DI_1;
    *DI2_flag = smart_power.switch_status.DI_2;
    xSemaphoreGive(switch_status_lock);
    return OK;
}

/**
 * @brief 获取端口电流统计
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_dev_current_get(uint8_t port_num , float * max_current,float * min_current)
{
    if(port_num < AISLE_24V || port_num > AISLE_220V_5)
    {
        return ERROR_COM;
    }
    if(port_num < AISLE_220V_1)
    {
        xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
        if(smart_power.direct_loop[port_num - AISLE_24V].dev_type == 0 || smart_power.direct_loop[port_num - AISLE_24V].dev_type > DEV_LIGHTNING_PROTECTOR)
        {
            xSemaphoreGive(direct_loop_lock);
            return ERROR_COM;
        }
        *max_current = smart_power.direct_loop[port_num - AISLE_24V].max_current;
        *min_current = smart_power.direct_loop[port_num - AISLE_24V].min_current;
        xSemaphoreGive(direct_loop_lock);
    }
    else
    {
        xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
        if(smart_power.alternating_loop[port_num - AISLE_220V_1].dev_type == 0 || smart_power.alternating_loop[port_num - AISLE_220V_1].dev_type > DEV_LIGHTNING_PROTECTOR)
        {
            xSemaphoreGive(alternating_loop_lock);
            return ERROR_COM;
        }
        *max_current = smart_power.alternating_loop[port_num - AISLE_220V_1].max_current;
        *min_current = smart_power.alternating_loop[port_num - AISLE_220V_1].min_current;
        xSemaphoreGive(alternating_loop_lock);
    }
    return OK;
}

/**
 * @brief 获取交流回路状态
 * @param alternating_status       220V回路状态结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_alternating_status(ALTERNATING_STATUS_t *alternating_status)
{
    if(NULL == alternating_status)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(switch_status_lock, portMAX_DELAY);
    alternating_status->v_Power_DECT1 = smart_power.switch_status.switch_status_220V.v_Power_DECT1;
    alternating_status->v_Power_DECT2 = smart_power.switch_status.switch_status_220V.v_Power_DECT2;
    alternating_status->v_Power_DECT3 = smart_power.switch_status.switch_status_220V.v_Power_DECT3;
    alternating_status->v_Power_DECT4 = smart_power.switch_status.switch_status_220V.v_Power_DECT4;
    alternating_status->v_Power_DECT5 = smart_power.switch_status.switch_status_220V.v_Power_DECT5;
    xSemaphoreGive(switch_status_lock);   
    return OK;
}

/**
 * @brief 获取直流回路状态
 * @param direct_status       220V回路状态结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_direct_status(DIRECT_STATUS_t *direct_status)
{
    return OK;
}

/**
 * @brief 获取漏电电流数据
 * @param leakage
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_leakage( uint32_t * leakage_communicate,uint32_t * leakage_light )
{
    Bl0939_Elect_t Elect_0939;
    Bl0906_Elect_t Elect_0906;
    if(NULL == leakage_communicate || NULL == leakage_light)
    {
        return ERROR_COM;
    }
    if(BSP_SUCCESS != Bl0939_GetElect(&bl0939_obj,&Elect_0939,BL0939_ELECT_ALL))
    {
        return ERROR_COM;
    }
    *leakage_communicate = (uint32_t)(Elect_0939.LeakCur_Value_A*1000);  //wh
    if(BSP_SUCCESS != Bl0906_GetElect(&bl0906_obj,&Elect_0906,BL0906_ELECT_L_6))
    {
        return ERROR_COM;
    }
    *leakage_light = (uint32_t)(Elect_0906.FAST_RMS_6*1000);
    log_i("leakage_communicate = %d \r\n",*leakage_communicate);
    log_i("leakage_light = %d \r\n",*leakage_light);
    return OK;
}

/**
 * @brief 重置电量计量
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_energy_reset(void)
{
    Bl0939_Energy_t Bl0939_energy;
    Bl0906_Energy_t Bl0906_energy;
//    Bl0939_energy.Energy_A = 0;
    Bl0939_energy.Energy_B = 0;

    if(BSP_SUCCESS != Bl0939_SetEnergy(&bl0939_obj,&Bl0939_energy))
    {
        return ERROR_COM;
    }
    Bl0906_energy.Energy_1 = 0;
    Bl0906_energy.Energy_2 = 0;
    Bl0906_energy.Energy_3 = 0;
    Bl0906_energy.Energy_4 = 0;
    Bl0906_energy.Energy_5 = 0;
//    Bl0906_energy.Energy_6 = 0;
    Bl0906_energy.Energy_Sum = 0;
    if(BSP_SUCCESS != Bl0906_SetEnergy(&bl0906_obj,&Bl0906_energy))
    {
        return ERROR_COM;
    }
    
    xSemaphoreTake(info_lock, portMAX_DELAY);
    smart_power.energy_communicate = 0;
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 设置电量计量
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_energy_set(void)
{
    Bl0939_Energy_t Bl0939_energy;
    Bl0906_Energy_t Bl0906_energy;
//    Bl0939_energy.Energy_A = 0;
    Bl0939_energy.Energy_B = smart_power.energy_communicate;
    if(BSP_SUCCESS != Bl0939_SetEnergy(&bl0939_obj,&Bl0939_energy))
    {
        return ERROR_COM;
    }
    Bl0906_energy.Energy_1 = smart_power.energy_light_1;
    Bl0906_energy.Energy_2 = smart_power.energy_light_2;
    Bl0906_energy.Energy_3 = 0;
    Bl0906_energy.Energy_4 = 0;
    Bl0906_energy.Energy_5 = 0;
//    Bl0906_energy.Energy_6 = 0;
    Bl0906_energy.Energy_Sum = smart_power.energy_light_1 + smart_power.energy_light_2;
    if(BSP_SUCCESS != Bl0906_SetEnergy(&bl0906_obj,&Bl0906_energy))
    {
        return ERROR_COM;
    }
    return OK;
}

/**
 * @brief 更新电量计量
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_energy_update(void)
{
    Bl0939_Energy_t Bl0939_energy;
    Bl0906_Energy_t Bl0906_energy;
    if(BSP_SUCCESS != Bl0939_GetEnergy(&bl0939_obj,&Bl0939_energy))
    {
        return ERROR_COM;
    }
    if(BSP_SUCCESS != Bl0906_GetEnergy(&bl0906_obj,&Bl0906_energy))
    {
        return ERROR_COM;
    }
    xSemaphoreTake(info_lock, portMAX_DELAY);
    smart_power.energy_communicate = Bl0939_energy.Energy_B;
    smart_power.energy_light_1 = Bl0906_energy.Energy_1;
    smart_power.energy_light_2 = Bl0906_energy.Energy_2;
    xSemaphoreGive(info_lock);
    return OK;
}

/**
 * @brief 主电源掉电动作
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_main_loop_power_down(void)
{
    uint8_t i = 0;
    xSemaphoreTake(direct_loop_lock, portMAX_DELAY);
    /* 直流回路 */
    for( i = 0 ; i < DIRECT_LOOP_LEN ; i++)
    {
        if(smart_power.direct_loop[i].dev_type != 0 && (smart_power.direct_loop[i].dev_type < DEV_GAT || smart_power.direct_loop[i].dev_type > DEV_ONU))
        {
            if(OK != app_control_switch_set(i + 1,SWITCH_CLOSE))
            {
                xSemaphoreGive(direct_loop_lock);
                return ERROR_COM;
            }
        }
    }
    xSemaphoreGive(direct_loop_lock);

    xSemaphoreTake(alternating_loop_lock, portMAX_DELAY);
    /* 交流回路 */
    for( i = 0 ; i < ALTERNATING_LOOP_LEN ; i++)
    {
        if(smart_power.alternating_loop[i].dev_type != 0 && (smart_power.alternating_loop[i].dev_type < DEV_GAT || smart_power.alternating_loop[i].dev_type > DEV_ONU))
        {
            if(OK !=  app_control_switch_set(i + 1 + AISLE_12V_485_2,SWITCH_CLOSE))
            {
                xSemaphoreGive(alternating_loop_lock);
                return ERROR_COM;
            }
        }
    }
    xSemaphoreGive(alternating_loop_lock);
    return OK;
}

/**
 * @brief LED show
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_oled_show_port(uint8_t oled_type)
{
    char row[20];
    char out_send[64];
    uint8_t rev_buffer[MAX_485_RECV];
    uint8_t num = 0;
    uint8_t i = 0;
    uint16_t offset = 0;
    uint16_t receive_len = 0;
    uint16_t alarm_arr[ALARM_OLED_MAX_LEN];
    if(oled_type > OLED_SHOW_ALARM)
    {
        return ERROR_COM;
    }
    if(oled_type == OLED_SHOW_PORT)
    {
        memset(out_send,0,64);
        memset(row,0,20);
        if(OK != Msc_Send(MSC_INTEL,CLEAN_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }

        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11," AC  | DC ");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }
        
        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11,"__________");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }
        
        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,24,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11,"12345|1234");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }

        uint8_t switch_status[11];
        for(i = 0 ; i < 11 ; i++)
        {
            if(OK != app_control_switch_get(i+1,&switch_status[i]))
            {
                return ERROR;
            }
        }
        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11,"%s%s%s%s%s %s%s%s%s",switch_status[6] == 1?"0":"X",switch_status[7] == 1?"0":"X",switch_status[8] == 1?"0":"X",switch_status[9] == 1?"0":"X",switch_status[10] == 1?"0":"X",switch_status[0] == 1?"0":"X",switch_status[1] == 1?"0":"X",switch_status[2] == 1?"0":"X",switch_status[3] == 1?"0":"X");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }
        
        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,1,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,48,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11,"__________");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }
    }
    else
    {
        memset(out_send,0,64);
        memset(row,0,20);
        if(OK != Msc_Send(MSC_INTEL,CLEAN_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }

        offset = 0; 
        memset(out_send,0,64);
        memset(row,0,20);
        PIN_STORE_CHAR(out_send,1,offset);
        PIN_STORE_CHAR(out_send,36,offset);
        PIN_STORE_CHAR(out_send,0,offset);
        PIN_STORE_CHAR(out_send,12,offset);
        PIN_STORE_CHAR(out_send,10,offset);
        snprintf(row,11," WARNING  ");
        PIN_STORE_BUFF(out_send,row,offset,10);
        if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
        {
            return ERROR_COM;
        }

        for( i = 0 ; i < ALARM_OLED_MAX_LEN ;i++)
        {
            alarm_arr[i] = 0;
        }
        /* 获取当前告警报警 */
        if(OK != Alarm_Get_Cur_Alarm((uint16_t *)alarm_arr,&num))
        {
            return ERROR_COM;
        }
        for( i = 0 ; i < ALARM_OLED_MAX_LEN ;i++)
        {
            offset = 0; 
            memset(out_send,0,64);
            memset(row,0,20);
            PIN_STORE_CHAR(out_send,1,offset);
            PIN_STORE_CHAR(out_send,36,offset);
            PIN_STORE_CHAR(out_send,(i+1)*12,offset);
            PIN_STORE_CHAR(out_send,12,offset);
            PIN_STORE_CHAR(out_send,10,offset);
            if(alarm_arr[i] == 0)
            {
                snprintf(row,11,"          ");
            }
            else
            {
                snprintf(row,11," %d      ",alarm_arr[i]);
            }
            PIN_STORE_BUFF(out_send,row,offset,10);
            if(OK != Msc_Send(MSC_INTEL,SHOW_STRING_OLED_CODE,(uint8_t *)out_send,offset,(uint8_t *)rev_buffer,&receive_len))
            {
                return ERROR_COM;
            }
        }
        
    }
    return OK;
}


/**
 * @brief 升级参数配置
 * @param upgrade_values    升级参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_upgrade_values_set( UPGRADE_VALUES_t * upgrade_values)
{
    if(NULL == upgrade_values)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(upgrade_lock, portMAX_DELAY);
    smart_power.upgrade_values.file_total_num = upgrade_values->file_total_num;
    smart_power.upgrade_values.upgrade_status = upgrade_values->upgrade_status;
    smart_power.upgrade_values.subfile_num = upgrade_values->subfile_num;
    smart_power.upgrade_values.wait_subfile_no = upgrade_values->wait_subfile_no;
	smart_power.upgrade_values.upgrade_source = upgrade_values->upgrade_source;
    memcpy(smart_power.upgrade_values.upgrade_version,upgrade_values->upgrade_version,UPGRADE_VERSION_LEN);
    memcpy(smart_power.upgrade_values.sha256,upgrade_values->sha256,UPGRADE_SHA256_LEN);
    xSemaphoreGive(upgrade_lock);
    return OK;
}

/**
 * @brief 升级参数获取
 * @param upgrade_values    升级参数结构体
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_upgrade_values_get( UPGRADE_VALUES_t * upgrade_values)
{
    if(NULL == upgrade_values)
    {
        return ERROR_COM;
    }
    xSemaphoreTake(upgrade_lock,portMAX_DELAY);
    upgrade_values->file_total_num = smart_power.upgrade_values.file_total_num;
    upgrade_values->upgrade_status = smart_power.upgrade_values.upgrade_status;
    upgrade_values->subfile_num = smart_power.upgrade_values.subfile_num;
    upgrade_values->wait_subfile_no = smart_power.upgrade_values.wait_subfile_no;
	upgrade_values->upgrade_source = smart_power.upgrade_values.upgrade_source;
    memcpy(upgrade_values->upgrade_version,smart_power.upgrade_values.upgrade_version,UPGRADE_VERSION_LEN);
    memcpy(upgrade_values->sha256,smart_power.upgrade_values.sha256,UPGRADE_SHA256_LEN);
    xSemaphoreGive(upgrade_lock);
    return OK;
}

/**
 * @brief 心跳包参数上报
 * @return uint8_t OK：成功  ERROR_COM：失败
 */
int32_t app_control_heart_package_report(void)
{
    uint8_t out_send = 0;
    uint8_t rev_buffer[MAX_485_RECV];
    uint16_t receive_len = 0;

    return Msc_Send(MSC_ETH,CMD_HEART,&out_send,0,rev_buffer,&receive_len);
}

/**
 * @brief 通信参数配置
 * @param upgrade_values    升级参数结构体
 */
void app_control_up_type_set( uint8_t up_type)
{
    smart_power.up_type = up_type;
}

/**
 * @brief 通信参数获取
 * @param upgrade_values    升级参数结构体
 */
void app_control_up_type_get( uint8_t *up_type)
{
     *up_type = smart_power.up_type ;
}
#endif /* BOARD_PCU_EN */
